﻿using ErrorOr;
using Gym.Domain.Common;
using Gym.Domain.GymAggregate.Events;
using Gym.Domain.RoomAggregate;
using Gym.Domain.TrainerAggregate;

namespace Gym.Domain.GymAggregate
{
    public class Gym : AggregateRoot
    {                
        private readonly int _maxRooms;
        private readonly List<Guid> _roomIds = new();
        private readonly List<Guid> _trainerIds = new();

        public string Name { get; } = null!;

        public Guid SubscriptionId { get; }
        public Gym(
            string name,
            int maxRooms,
            Guid subscriptionId,
            Guid? id = null) : base(id ?? Guid.NewGuid())
        {
            Name = name;
            _maxRooms = maxRooms;
            SubscriptionId = subscriptionId;
        }

        public ErrorOr<Success> AddRoom(Room room)
        {
            if (_roomIds.Contains(room.Id))
            {
                return Error.Conflict(description:"健身房已存在该房间");
            }
            if (_roomIds.Count >= _maxRooms)
            {
                return GymErrors.CannotHaveMoreRoomsThanSubscriptionAllows;
            }
            _roomIds.Add(room.Id);

            _domainEvents.Add(new RoomAddedEvent(this,room));

            return Result.Success;
        }

        public bool HasRoom(Guid roomId)
        {
            return _roomIds.Contains(roomId);
        }

        public ErrorOr<Success> AddTrainer(Trainer trainer)
        {
            if (_trainerIds.Contains(trainer.Id))
            {
                return Error.Conflict(description: "教练已分配给该健身房");
            }

            _trainerIds.Add(trainer.Id);

            return Result.Success;
        }

        public bool HasTrainer(Guid trainerId)
        {
            return _trainerIds.Contains(trainerId);
        }

        public ErrorOr<Success> RemoveRoom(Room room)
        {
            if (!_roomIds.Contains(room.Id))
            {
                return Error.NotFound(description: "没有找到该房间");
            }

            _roomIds.Remove(room.Id);

            _domainEvents.Add(new RoomRemovedEvent(this,room));

            return Result.Success;
        }

        private Gym()
        {
        }
    }
}
